//
// Created by WenYF on 2016/11/2.
//
// 队列先进先出，不阻塞

#include "queue.h"

typedef struct ifelement_struct {
    void *data;
    struct ifelement_struct *next;
} ifelement;

typedef struct ifqueue_struct {
    int size;
    ifelement *front;
    ifelement *rear;
} ifqueue;

// 构造一个队列
void* if_queue_new() {
    ifqueue *queue = (ifqueue*) malloc (sizeof(ifqueue));
    queue->size = 0;
    queue->front = NULL;
    queue->rear = NULL;

    return (void*)queue;
}

// 添加一个到队尾
void if_queue_add(void *q, void *data) {
    if (!data || !q) {
        return;
    } else {
        ifqueue *queue = (ifqueue *) q;
        ifelement *element = (ifelement*) malloc (sizeof(ifelement));
        logD("add data addr = %d", data);
        element->data = data;
        element->next = NULL;
        if (queue->size == 0) {
            // 队列为空
            // 首尾指向同一个
            queue->front = element;
            queue->rear = element;
        } else {
            // 尾部指向新的
            queue->rear->next = element;
            queue->rear = element;
        }
        queue->size++;
    }
}

// 得到第一个，并从队列移除
// return: null or 数据指针
void* if_queue_poll(void *q) {
    if (!q) {
        return NULL;
    } else {
        ifelement *frontEle = NULL;
        ifqueue *queue = (ifqueue *) q;
        void* data = NULL;
        if (queue->size == 0) {
            return NULL;
        } else if (queue->size == 1) {
            frontEle = queue->front;
            queue->front = NULL;
            queue->rear = NULL;
        } else {
            frontEle = queue->front;
            queue->front = frontEle->next;
        }

        queue->size--;

        data = frontEle->data;
        free(frontEle);

        logD("poll data addr = %d", data);
        return data;
    }
}

// 得到第一个，不从队列移除
void* if_queue_peek(void *q) {
    if (!q) {
        return NULL;
    } else {
        ifqueue *queue = (ifqueue *) q;
        ifelement *frontEle = queue->front;

        if (frontEle) {
            void* data = frontEle->data;
            return data;
        } else {
            return NULL;
        }
    }
}

// 清除所有
// 只会清理队列，不会清理队列中的数据，数据需要调用者自己清理
void if_queue_clear(void *q) {
    if (!q) {
        return;
    } else {
        ifqueue *queue = (ifqueue *) q;
        ifelement *ele = queue->front;
        ifelement *elePre = NULL;
        while (ele) {
            elePre = ele;
            ele = ele->next;
            free(elePre);
        }

        queue->size = 0;
        queue->front = NULL;
        queue->rear = NULL;
    }
}

// 得到长度
// return: -1参数为null，其他表示大小
int if_queue_length(void *q) {
    if (!q) {
        return -1;
    } else {
        ifqueue *queue = (ifqueue *) q;
        return queue->size;
    }
}

// 释放队列
void if_queue_delete(void *q) {
    if (!q) {
        return;
    } else {
        if_queue_clear(q);
        free(q);
    }
}



